package com.wawu.server.service;

import com.wawu.common.annotation.IOC.Autowired;
import com.wawu.common.annotation.IOC.component.Service;
import com.wawu.common.annotation.controller.parameter.RequestBody;
import com.wawu.common.constant.JwtClaimsConstant;
import com.wawu.common.constant.MessageConstant;
import com.wawu.common.exception.LoginException;
import com.wawu.common.property.JwtProperties;
import com.wawu.common.result.Result;
import com.wawu.common.utils.JwtUtil;
import com.wawu.pojo.dto.LoginDTO;
import com.wawu.pojo.entity.Order;
import com.wawu.pojo.entity.User;
import com.wawu.pojo.vo.LoginVO;
import com.wawu.pojo.vo.getDataVO;
import com.wawu.server.dao.UsersDAO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.impl.JwtMap;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
import org.mindrot.jbcrypt.BCrypt;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserService {
    @Autowired
    private UsersDAO usersDAO;

    //涉及到各种密码加密的一些东西
    int saltRounds = 5; // 定义盐的复杂度
    String salt = BCrypt.gensalt(saltRounds);

    public LoginVO login(@RequestBody LoginDTO loginDTO) throws SQLException {
        User user = usersDAO.getUser(User.builder().email(loginDTO.getAccount()).build());
        //账号没有注册
        if(user==null){
            throw new LoginException(MessageConstant.LOGIN_EMAIL_NOT_REGISTER);
        }
        System.out.println(loginDTO);
        System.out.println(user);
        LoginVO loginVO=new LoginVO();
        //校验密码
        if(BCrypt.checkpw(loginDTO.getPwd(),user.getPwd())){
            loginVO.setName(user.getNickname());
                //JWT令牌存储内容：用户id
            Map<String,Object> claims=new HashMap<>();//存放对应的的角色信息
            claims.put(JwtClaimsConstant.USER_ID,user.getId());
            loginVO.setToken(JwtUtil.createJWT(JwtProperties.secretKey,JwtProperties.ttl,claims));
            System.out.println(JwtUtil.parseJWT(JwtProperties.secretKey,loginVO.getToken()));
        }else{
            throw new LoginException(MessageConstant.LOGIN_PWD_NOT_ERROR);
        }

        return loginVO;
    }

    /**
     * 注册用户
     * @param newUser
     * @return
     */
    public LoginVO signup(User newUser) throws SQLException {
        //1. 判断是否已经被注册
        User user = usersDAO.getUser(User.builder()
                .email(newUser.getEmail()).build());
        if(user!=null){
            throw new LoginException(MessageConstant.LOGIN_EMAIL_HAD_REGISTER);
        }
        user = usersDAO.getUser(User.builder()
                .nickname(newUser.getNickname()).build());
        if(user!=null){
            throw new LoginException(MessageConstant.LOGIN_NICKNAME_HAD_REGISTER);
        }

        //2. 插入数据
        newUser.setCreatetime(LocalDateTime.now());
        newUser.setUpdatetime(LocalDateTime.now());
        newUser.setPwd(BCrypt.hashpw(newUser.getPwd(),salt));
        newUser.setId(usersDAO.insert(newUser));
        //3. 前端需要的返回数据
        LoginVO loginVO=new LoginVO();
        loginVO.setName(newUser.getNickname());
            //JWT令牌存储内容：用户id
        Map<String,Object> claims=new HashMap<>();//存放对应的的角色信息
        claims.put(JwtClaimsConstant.USER_ID,newUser.getId());
        loginVO.setToken(JwtUtil.createJWT(JwtProperties.secretKey,JwtProperties.ttl,claims));
        System.out.println(JwtUtil.parseJWT(JwtProperties.secretKey,loginVO.getToken()));
        return loginVO;
    }

    public List<getDataVO> getdata(HttpServletRequest request) throws SQLException, InvocationTargetException, IllegalAccessException {
        String token = request.getHeader("token");
        Claims claims = JwtUtil.parseJWT(JwtProperties.secretKey, token);
        Long userId = Long.parseLong(claims.get(JwtClaimsConstant.USER_ID).toString());

        List<User> dataList = usersDAO.getData(User.builder().id(userId).build());
        List<getDataVO> userDataVOList = new ArrayList<>();
        for(User data:dataList){
            getDataVO dataVO=new getDataVO();
            BeanUtils.copyProperties(dataVO,data);
            userDataVOList.add(dataVO);
        }
        return userDataVOList;
    }

    public static void main(String[] args) {
        //测试下bcrypt加密
        String pwd="password2";
        String dbPwd="$2a$10$SYwliJBnXvX65qfauY.MROLoKFn5VjfzrwqIgbWGAcUGEl/1K3Vde";//数据库中的密码(经过加密)
        int saltRounds = 5; // 定义盐的复杂度
        String salt = BCrypt.gensalt(saltRounds);
            //1.测试每次生成是否相同
        System.out.println(BCrypt.hashpw(pwd,salt));
        System.out.println(BCrypt.hashpw(pwd,salt));
        System.out.println(BCrypt.hashpw(pwd,salt));
                //测试结果为加密结果都相同
            //2.校验密码
        System.out.println(BCrypt.checkpw(pwd,dbPwd));
        System.out.println(BCrypt.checkpw(pwd,dbPwd));
        System.out.println(BCrypt.checkpw(pwd,dbPwd));
        pwd="654321";
        System.out.println(BCrypt.checkpw(pwd,dbPwd));
        System.out.println(BCrypt.checkpw(pwd,dbPwd));
        System.out.println(BCrypt.checkpw(pwd,dbPwd));

    }
}
